home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
color.arc
/
COLOR1.ASM
< prev
Wrap
Assembly Source File
|
1987-01-08
|
23KB
|
470 lines
TITLE COLOR January 7, 1987
;
; Note: This version is slightly different from the COLOR.COM
; Program furnished. It does not include the procedure
; for determining available computer memory. This
; procedure has nothing to do with the COLOR program and
; I wish to keep it proprietary.
;
; Happy programming,
; Jeff Kallevig
; Crestwood Elite
; 9804 Dell Road
; Eden Prairie, MN 55344
;
;
; COLOR.ASM -- Memory resident screen color --
; --------- ----------------------------------
Code SEGMENT PARA PUBLIC 'CODE' ; Code segment begins here
ASSUME CS:Code, DS:Code, ES:Code, SS:Code
ORG 100h ; Directive needed for .COM programs
Start: JMP Loader ; Skip down to the program
DB 13
Logo DB '╔═══════════════════════════════════╗', 13,10
Header DB '║ COLOR POWER Version 1.?? ║', 13,10
Footer DB '║ ║', 13,10
DB '║ Copyright 1986 by Crestwood Elite ║', 13,10
DB '╚═══════════════════════════════════╝', 13,10
EndLogo DB 26
NewColor DB 7 ; Screen (Text) color
Border DB 0 ; Default border color
Int10h DD ? ; The original 10h Interrupt address
Video: CMP AH,6 ; Scroll Window Up ?
JE NewUpDn ; Yes, so do NewUpDn.
CMP AH,7 ; Scroll Window Down ?
JE NewUpDn ; Yes, so do NewUpDn.
CMP AH,0 ; Set Video Mode ?
JE NewMode ; Yes, so do NewMode.
CMP AH,9 ; Write Character and Attribute ?
JNE Display ; No, so all done
CMP BL,7 ; Yes, so is character Light Grey ?
JNE Display ; No, so all done
MOV BL,CS:NewColor ; Yes, so substitute NewColor.
Display: JMP CS:Int10h ; All done, do original Interrupt 10h.
NewUpDn: CMP BH,7 ; Is color set to Light Grey ?
JNE NewMode ; No, so don't change it.
MOV BH,CS:NewColor ; Yes, so substitute NewColor
NewMode: PUSHF ; Simulate the Video Interrupt
CALL CS:Int10h ; by calling the original Interrupt.
PUSH DX ; Preserve these registers.
PUSH AX
MOV DX,03D9h ; Set the CGA I/O Port
MOV AL,CS:Border ; to the Border Color
OUT DX,AL ; by writing directly to it.
POP AX ; Restore these registers.
POP DX
IRET ; Return to the caller.
;****************************************************************************
; *
EndRes LABEL BYTE ; End of resident part of program *
; *
;****************************************************************************
;-----------------------------------------------------------------------------
; ErrMsg displays the message. ( Does not preserve any registers! )
;
; Entry: SwapBX -- must contain OFFSET address of the message
; SwapCX -- must contain length of message (^Z also ends msg)
; Color -- the attribute for the message
;-----------------------------------------------------------------------------
SwapBX DW 0 ; Temp storage for BX
SwapCX DW 0 ; Temp storage for CX
Color DB 30 ; Yellow on Blue
ErrMsg PROC NEAR
PUSH CX
MOV AH,15 ; Get page and mode numbers
INT 10h ; by calling BIOS.
CMP Color,0 ; Check color flag
JNE SetColor ; If not 0, then set to color number
MOV AH,8 ; Read Character and Attribute
INT 10h ; by calling BIOS.
MOV BL,AH ; Set to the original screen color
JMP ShowMsg ; and skip down
SetColor:
MOV BL,112 ; Default to monochrome reverse video
CMP AL,7 ; Is it set for monochrome ?
JE ShowMsg ; Yes, then skip down.
MOV BL,Color ; No, set to Color
ShowMsg:
MOV AH,3 ; Read Cursor Position
INT 10h ; by calling BIOS.
XCHG SwapBX,BX ; Preserve page & color, set index
MOV CX,SwapCX ; Counter for message string
DisplayLoop:
MOV SwapCX,CX ; Preserve character counter
MOV AL,[BX] ; Put the message char into AL
CMP AL,13 ; Is it carriage return ?
JE CarRet ; Yes, so skip down.
CMP AL,10 ; Is it a line feed ?
JE LineFeed ; Yes, so skip down.
CMP AL,9 ; Is it a tab ?
JE TabOver ; Yes, so move cursor over.
CMP AL,26 ; Is it a ^Z EOF marker ?
JE EndMsg ; Yes, then all done.
MOV AH,9 ; Write Character & Attribute.
MOV CX,1 ; write the character once
XCHG BX,SwapBX ; Restore BX, put index into SwapBX
INT 10h ; by calling BIOS.
INC DL ; Advance the cursor.
NewPosition:
MOV AH,2h ; Set Cursor Position
INT 10h ; by calling BIOS.
XCHG SwapBX,BX ; Restore index BX, put BX in SwapBX
INC BX ; Advance the index count
MOV CX,SwapCX ; Restore character counter
LOOP DisplayLoop ; Continue to display more.
JMP EndMsg ; All done here.
CarRet:
XCHG BX,SwapBX ; Restore BX, put index into SwapBX
MOV DL,0 ; Cursor set to first column
JMP NewPosition ; and continue.
LineFeed:
XCHG BX,SwapBX ; Restore BX, put index into SwapBX
INC DH ; No, so just continue.
JMP NewPosition ; and continue.
TabOver:
XCHG BX,SwapBX ; Restore BX, put index into SwapBX
ADD DL,8 ; Advance cursor 8 spaces.
JMP NewPosition ; and continue.
EndMsg:
XCHG BX,SwapBX ; Restore BX, put index into SwapBX
POP CX
RET ; Done here
ErrMsg ENDP
;-----------------------------------------------------------------------------
; ClearScreen clears the entire screen
;-----------------------------------------------------------------------------
ClearScreen PROC NEAR
PUSH AX ; Preserve the registers used
PUSH BX
PUSH CX
PUSH DX
MOV AH,15 ; Get Current Video Mode (page)
INT 10h ; by calling BIOS.
MOV BH,7 ; Set display color
MOV AH,6 ; Scroll Window Up
MOV AL,0 ; Clear Screen
MOV CH,0 ; top
MOV CL,0 ; left
MOV DH,24 ; bottom
MOV DL,79 ; right
INT 10h ; by calling BIOS.
MOV AH,15 ; Get Current Video Mode (page)
INT 10h ; by calling BIOS.
MOV AH,2h ; Set Cursor Position
MOV DX,0 ; to the top left corner
INT 10h ; by calling BIOS.
POP DX ; Restore the registers.
POP CX
POP BX
POP AX
RET ; All done here.
ClearScreen ENDP
;-----------------------------------------------------------------------------
; ParmString is called to get any command line parameters and process
; them as needed.
;-----------------------------------------------------------------------------
ParmLen DB 0 ; Number of parameter characters passed
MenuParm DB ' Menu procedure for the COLOR program. '
DB 10,13,' Reset to grey text, no border. ',26
ParmString PROC NEAR
ASSUME CS:CODE, DS:CODE, ES:CODE, SS:CODE
CLD ; Prepair for string movements.
MOV AX,CS ; Get the code segment
MOV ES,AX ; to set ES
MOV DS,AX ; and DS to the same segment.
SetParm: MOV SI,0080h ; Address to search in PSP
MOV DI,OFFSET ParmLen ; Set destination for parameter string.
MOVSB ; Put in the parameter length byte.
MOV CL,ParmLen ; Transfer length byte to counter
MOV CH,0 ; and make sure counter is set.
JCXZ NoParm ; No parameters, so done here.
INC CX ; Set counter for LOOP(E) functions
SUB DX,DX ; Set DX to zero
SUB BX,BX ; Set BX to zero
CALL NewParm ; Get the text color
CMP DL,0 ; Color Specified ?
JE NoParm ; No parameters specified.
MOV NewColor,DL ; Yes, so record it
SUB AX,AX ; Set AX to zero
MOV AL,DL ; Put color into AX
MOV DX,0010h ; Prepair for divide by 16
DIV DL ; Get the background color
MOV Border,AL ; for the border color default
SUB DX,DX ; Set DX to zero
SUB BX,BX ; Set BX to zero
MOV ColrFlag,0 ; Reset flag
CALL NewParm ; Get the border color
CMP ColrFlag,0 ; Color Specified ?
JE PutParm ; No parameters specified.
MOV Border,DL ; Yes, set the border color.
PutParm: RET ; All done here.
NoParm: CALL ShowHelp
RET ; All done here
ParmString ENDP
;-----------------------------------------------------------------------------
; NewParm checks the characters of a parameter. If numeric, they are
; converted to binary with result left in DX.
;-----------------------------------------------------------------------------
ColrFlag DB 0
BadParm DB 9,' ERROR -- Color number non-numeric. ',26
BigParm DB 9,' ERROR -- Color number too large. ',26
NewParm PROC NEAR
LODSB ; Get the first character
CMP AL,20h ; Is it a space ?
LOOPE NewParm ; Yes, so continue looking
JMP RunParm ; No, so skip down to check it out
GetParm: LODSB ; Get the next character
CMP AL,20h ; Is it a space ?
JE EndParm ; Yes, so end of parameter
RunParm: CMP AL,0Dh ; Carriage Return ?
JE EndParm ; Yes, so end of parameters
CMP AL,30h ; Zero ?
JB ParmBad ; Below is a bad parm character
CMP AL,39h ; Nine ?
JA ParmBad ; Above is a bad parm character
AND AX,000Fh ; Convert it to a decimal number.
MOV ColrFlag,1 ; Got a valid number
MOV BX,DX ; Save the number (0 first time round)
SHL DX,1 ; multiply by two
SHL DX,1 ; multiply by two
ADD DX,BX ; add original number
SHL DX,1 ; multiply by two ( = Times ten )
ADD DX,AX ; Add up the number
LOOP GetParm ; Continue thru the number
EndParm: CMP DX,00FFh ; Is the number TOO BIG ?
JA ParmBig ; Yes, so EXIT with ERROR message
RET ; No, so done here.
ParmBad: MOV SwapBX,OFFSET BadParm ; Point to message
MOV SwapCX,40 ; and set it's max length.
CALL ErrMsg ; Display the message
MOV AH,4Ch ; Terminate Process (return to DOS)
MOV AL,0 ; with an ERROR LEVEL = 1
INT 21h ; by calling DOS
; INT 20h ; Fast way out instead of above.
ParmBig: MOV SwapBX,OFFSET BigParm ; Point to message
MOV SwapCX,40 ; and set it's max length.
CALL ErrMsg ; Display the message
MOV AH,4Ch ; Terminate Process (return to DOS)
MOV AL,0 ; with an ERROR LEVEL = 1
INT 21h ; by calling DOS
; INT 20h ; Fast way out instead of above
NewParm ENDP
;-----------------------------------------------------------------------------
; ShowHelp displays a screen of help instructions
;-----------------------------------------------------------------------------
SaveColor DB 0
HelpScreen DB 9,9,'C O L O R P O W E R by Crestwood Elite',13,10
DB 13,10
DB 9,'No color parameter was specified. Use the table below to',13,10
DB 9,'see the color numbers. Include the number on the command',13,10
DB 9,'line to set the screen default color. You may optionally ',13,10
DB 9,'set the border color at the same time with a second number.',13,10
DB 13,10
DB 9,'COLOR 23 4 will set gray text on blue with a red border.',13,10
DB 13,10
DB '┌────────┬───────────────────────────────────────────────────────────────┐',13,10
DB '│ SCREEN │ TEXT colors First = Normal Second = Hi-Intensity │',13,10
DB '│ Bakgnd ├───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┤',13,10
DB '│ Colors │ Black │ Blue │ Green │ Cyan │ Red │Magenta│ Brown │ White │',13,10
DB '├────────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┤',13,10
DB '│ Black │ 0 8│ 1 9│ 2 10│ 3 11│ 4 12│ 5 13│ 6 14│ 7 15│',13,10
DB '│ Blue │ 16 24│ 17 25│ 18 26│ 19 27│ 20 28│ 21 29│ 22 30│ 23 31│',13,10
DB '│ Green │ 32 40│ 33 41│ 34 42│ 35 43│ 36 44│ 37 45│ 38 46│ 39 47│',13,10
DB '│ Cyan │ 48 56│ 49 57│ 50 58│ 51 59│ 52 60│ 53 61│ 54 62│ 55 63│',13,10
DB '│ Red │ 64 72│ 65 73│ 66 74│ 67 75│ 68 76│ 69 77│ 70 78│ 71 79│',13,10
DB '│ Magenta│ 80 88│ 81 89│ 82 90│ 83 91│ 84 92│ 85 93│ 86 94│ 87 95│',13,10
DB '│ Brown │ 96 104│ 97 105│ 98 106│ 99 107│100 108│101 109│102 110│103 111│',13,10
DB '│ White │112 120│113 121│114 122│115 123│116 124│117 125│118 126│119 127│',13,10
DB '└────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┘'
DB 32,26
ShowHelp PROC NEAR
CALL ClearScreen
MOV Color,3 ; Set color to cyan
MOV SwapBX,OFFSET HelpScreen ; Point to message
MOV SwapCX,756 ; and set it's max length.
CALL ErrMsg ; Display the message
MOV Color,0 ; Set color
MOV CX,8
MsgLoop: MOV SwapCX,4 ; and set it's max length.
CALL ErrMsg ; Display the message
ADD Color,8 ; Set color
MOV SwapCX,3 ; and set it's max length.
CALL ErrMsg ; Display the message
MOV AL,Color
MOV SaveColor,AL
MOV Color,3 ; Set color
MOV SwapCX,1 ; and set it's max length.
CALL ErrMsg ; Display the message
MOV AL,SaveColor
MOV Color,AL
SUB Color,7 ; Set color
LOOP MsgLoop
MOV AL,Color
ADD AL,8
MOV SaveColor,AL
MOV Color,3 ; Set color
MOV SwapCX,12 ; and set it's max length.
CALL ErrMsg ; Display the message
MOV CX,8
MOV AL,SaveColor
MOV Color,AL
CMP AL,119
JB MsgLoop
MOV Color,3 ; Set color
MOV SwapCX,64 ; and set it's max length.
CALL ErrMsg ; Display the message
MOV Color,7 ; Set color
MOV SwapCX,1 ; and set it's max length.
CALL ErrMsg ; Display the message
MOV AH,4Ch ; Terminate Process (return to DOS)
MOV AL,0 ; with an ERROR LEVEL = 1
INT 21h ; by calling DOS
; INT 20h ; Fast way out instead of above
ShowHelp ENDP
;-----------------------------------------------------------------------------
; Loader first checks if the program has already been loaded.
; If it is ready, it initializes the new printer interrupt.
;-----------------------------------------------------------------------------
Loader: ASSUME DS:CODE, ES:CODE, SS:CODE
CALL ParmString
MOV Header[33],'0' ; Revision level prevents false match
MOV Header[34],'1'
CLD
MOV DX,CS ; This segment
SUB AX,AX ; Beginning of search
MOV ES,AX ; Search segment
SearchLoop:
MOV SI,OFFSET Header ; Address to search
MOV CX,OFFSET Footer - OFFSET Header ; Length of search string
MOV DI,SI ; Set pointers to same address
REPZ CMPSB ; Check for match
JZ AlreadyLoaded ; If label matches, then already loaded
INC AX ; Still the search segment
MOV ES,AX ; ES to next segment
CMP AX,DX ; Check if it's this segment
JNZ SearchLoop ; Try another compare
JMP MakeResident ; Since no match found, proceed to
; set up and remain resident.
AlreadyLoaded:
ADD DI,OFFSET NewColor - OFFSET Footer ; Point to Colors in memory
ADD SI,OFFSET NewColor - OFFSET Footer ; Point to Colors in memory
MOV CX,2 ; Reset the 2 colors
REP MOVSB ; by storing their values.
CALL ClearScreen ; Display the new colors
MOV AH,4Ch ; Terminate Process (return to DOS)
SUB AL,AL ; with an ERROR LEVEL = 0
INT 21h ; by calling DOS
MakeResident:
MOV AH,35h ; Get Interrupt Vector address
MOV AL,10h ; for Video Services
INT 21h ; by calling DOS.
MOV WORD PTR Int10h[2],ES ; Transfer the vector base address
MOV WORD PTR Int10h,BX ; and it's offset address
PUSH CS ; Set DS to this programs Code segment
POP DS ; for the new vector base address
MOV DX,OFFSET Video ; and now it's offset
MOV AH,25h ; to set Interrupt Vector address
MOV AL,10h ; for Video Services
INT 21h ; by calling DOS.
CALL ClearScreen ; Clear the screen
MOV SwapBX,OFFSET Logo ; Point to message
MOV SwapCX,250 ; and set it's max length.
CALL ErrMsg ; Display the message
MOV Color,0 ; Set to original screen color
; NOTE: This procedure was deleted, proprietary material!
; CALL TellSize ; Display the memory allocations
; NOTE: This procedure was deleted, proprietary material!
MOV DX,OFFSET EndRes ; Set to keep only the resident part.
INT 27h
Code ENDS
END Start
DX,OFFSET EndRes ; Set to keep only the resident part.
INT 27h
Code ENDS